//
// Created by sunc on 20-10-16.
//

#include <vector>
#include <algorithm>
#include "caffe/layers/clip_layer.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe {

    template<typename Dtype>
    void ClipLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*> &bottom, const vector<Blob<Dtype>*> &top) {
        ClipParameter param = this->layer_param().clip_param();
        min_ = param.has_min() ? param.min() : std::numeric_limits<float>::min();
        max_ = param.has_max() ? param.max() : std::numeric_limits<float>::max();
    }

    template<typename Dtype>
    void ClipLayer<Dtype>::Reshape(const vector<Blob<Dtype>*> &bottom, const vector<Blob<Dtype>*> &top) {
        CHECK_EQ(bottom.size(), 1);
        CHECK_EQ(top.size(), 1);
        top[0]->ReshapeLike(*bottom[0]);
    }

    template<typename Dtype>
    void ClipLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*> &bottom, const vector<Blob<Dtype>*> &top) {
        Dtype *top_data = top[0]->mutable_cpu_data();
        const Dtype *bottom_data = bottom[0]->cpu_data();
        for (int i = 0; i < bottom[0]->count(); ++i) {
            top_data[i] = std::min<Dtype>(std::max<Dtype>(bottom_data[i], min_), max_);
        }
    }
    INSTANTIATE_CLASS(ClipLayer);
    REGISTER_LAYER_CLASS(Clip);
}  // namespace caffe
